#include "tracermanager.h"

TracerManager::TracerManager(QCustomPlot *_plot, QObject *parent)
    : QObject(parent)
    , m_xTracer(Q_NULLPTR)
    , m_yTracer(Q_NULLPTR)
    , m_lineTracer(Q_NULLPTR)
    , m_customPlot(_plot)
{

    // 创建标签
#if 0

#else
    m_mouseLabel = new QCPItemText(m_customPlot);
    m_mouseLabel->setLayer("overlay");
    m_mouseLabel->setClipToAxisRect(false);
    m_mouseLabel->setPadding(QMargins(5, 5, 5, 5));
    m_mouseLabel->setBrush(QBrush(QColor(244, 244, 244, 100)));
    m_mouseLabel->setPen(QPen(Qt::black));
    m_mouseLabel->setFont(QFont("Arial", 8));
    m_mouseLabel->setVisible(true);
#endif

//    // 绑定监听移动信号
//    connect(m_customPlot, &QCustomPlot::mouseMove, this, &TracerManager::do_mouseMove);

    qDebug() << "TracerManager初始化函数";

    setTracerEnabled(true);
}

TracerManager::~TracerManager()
{
    if(!m_dataTracers.isEmpty()) {
        qDeleteAll(m_dataTracers);
    }

    if(m_xTracer) {
        m_xTracer->deleteLater();
    }

    if(m_yTracer) {
        m_yTracer->deleteLater();
    }

    if(m_lineTracer) {
        m_lineTracer->deleteLater();
    }

    if(m_mouseLabel) {
        m_mouseLabel->deleteLater();
    }
}

void TracerManager::do_mouseMove(QMouseEvent *event)
{
//    qDebug() << "QCustomPlot鼠标移动信号来了";

    // 更新追踪器位置
    do_updataPosition(event);


    // 是否离开、进入窗口
    QRect plotRect = m_customPlot->rect();
    QPoint currPos = event->pos();
    static QPoint lastPos = event->pos();

    if (!plotRect.contains(currPos)) {
        qDebug() << "鼠标离开窗口边界";
    } else if (lastPos.isNull()) {
        qDebug() << "鼠标进入窗口";
    }
    lastPos = currPos; // 保存最后坐标用于增量判断
}

void TracerManager::do_updataPosition(QMouseEvent *event)
{
    if(!m_enabled) return;
#if 0
    // 坐标转换
    const double x_val = m_customPlot->xAxis->pixelToCoord(event->x());
    const double y_val = m_customPlot->yAxis->pixelToCoord(event->y());

    qDebug() << "坐标转换:" << x_val << ", " << y_val;
#else
    // 获取当前鼠标位置（像素坐标）
    int x_pos = event->pos().x();
    int y_pos = event->pos().y();
//    qDebug() << "坐标:" << x_pos << ", " << y_pos;

    // 将像素坐标转换为实际的x,y轴的坐标
    double x_val = m_customPlot->xAxis->pixelToCoord(x_pos);
    double y_val = m_customPlot->yAxis->pixelToCoord(y_pos);

//    qDebug() << "坐标转换:" << x_val << ", " << y_val;
#endif
    // 更新鼠标位置
    updateMouseLabelPosition(m_mouseLabel, x_val, y_val);

    // 如果x轴追踪器不存在，则创建并初始化
    if(Q_NULLPTR == m_xTracer)
        m_xTracer = new MyTracer(m_customPlot, MyTracer::XAxisTracer);//x轴
    // 更新x轴追踪器的位置
    m_xTracer->updatePosition(x_val, y_val);

    // 如果y轴追踪器不存在，则创建并初始化
    if(Q_NULLPTR == m_yTracer)
        m_yTracer = new MyTracer(m_customPlot, MyTracer::YAxisTracer);//y轴
    // 更新y轴追踪器的位置
    m_yTracer->updatePosition(x_val, y_val);

    // 获取当前数据追踪器的数量和图表中的曲线数量
    int nTracerCount = m_dataTracers.count();
    int nGraphCount = m_customPlot->graphCount();

    // 如果数据追踪器数量小于曲线数量，则创建新的数据追踪器
    if(nTracerCount < nGraphCount)
    {
        for(int i = nTracerCount; i < nGraphCount; ++i)
        {
            MyTracer *tracer = new MyTracer(m_customPlot, MyTracer::DataTracer);
            m_dataTracers.append(tracer);
        }
    }
    // 如果数据追踪器数量大于曲线数量，则隐藏多余的追踪器
    else if(nTracerCount > nGraphCount)
    {
        for(int i = nGraphCount; i < nTracerCount; ++i)
        {
            if(!m_dataTracers[i]) {
                MyTracer *tracer = m_dataTracers[i];
                if(tracer)
                {
                    tracer->setVisible(false);
                }
            }
        }
    }

//    auto start = std::chrono::high_resolution_clock::now();

    // 更新每个数据追踪器的位置和样式
    for (int i = 0; i < nGraphCount; ++i)
    {
        QCPGraph *graph = m_customPlot->graph(i);
        MyTracer *tracer = m_dataTracers[i];

//        qDebug() << "graph:" << graph;
//        qDebug() << "tracer:" << tracer;

        // 如果追踪器不存在或已失效，创建新的
        if (!tracer) {
            tracer = new MyTracer(m_customPlot, MyTracer::DataTracer);
            tracer->setVisible(true);// 显示
        }
        // 设置追踪器的画笔、刷子和标签画笔
        tracer->setPen(graph->pen());
        tracer->setBrush(Qt::NoBrush);
        tracer->setLabelPen(graph->pen());

        tracer->setGraph(graph);    // 绑定Graph



#if 1
        // 查找对应x值的数据点
        auto iter = graph->data()->findBegin(x_val);
        double value = iter->mainValue();
#else
        // 使用 findBegin 快速定位左边界
        auto rightIter = graph->data()->findBegin(x_val);
        if (rightIter == graph->data()->constEnd()) {
            // 处理越界
            qDebug() << "x_val越界";
            return;
        }
        auto leftIter = (rightIter == graph->data()->constBegin()) ? rightIter : rightIter - 1;

        // 线性插值
        double x0 = leftIter->mainKey(), y0 = leftIter->mainValue();
        double x1 = rightIter->mainKey(), y1 = rightIter->mainValue();
        double y = y0 + (x_val - x0) * (y1 - y0) / (x1 - x0);
        double value(y);
#endif
//        qDebug() << "tracer:" << tracer << ", graph:" << graph  << " --> 更新追踪器的位置";
        // 更新追踪器的位置
        tracer->updatePosition(x_val, value);
    }
//    auto end = std::chrono::high_resolution_clock::now();
//    qDebug() << "Time: " << std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() << "μs\n";


    // 如果直线追踪器不存在，则创建并初始化
    if(Q_NULLPTR == m_lineTracer)
        m_lineTracer = new MyTraceLine(m_customPlot, MyTraceLine::Both);//直线
    // 更新直线追踪器的位置
    m_lineTracer->updatePosition(x_val, y_val);

    // 重新绘制图表
    m_customPlot->replot(QCustomPlot::rpQueuedReplot);

//    // 控制重绘频率
//    static QElapsedTimer timer;
//    if(timer.hasExpired(50)) {
//        m_customPlot->replot(QCustomPlot::rpQueuedReplot);
//        timer.start();
//    }
}

void TracerManager::setTracerEnabled(bool enabled)
{
    m_enabled = enabled;
    if(enabled) {
        connect(m_customPlot, &QCustomPlot::mouseMove, this, &TracerManager::do_mouseMove);
    } else {
        disconnect(m_customPlot, &QCustomPlot::mouseMove, this, &TracerManager::do_mouseMove);
    }
}
///
/// \brief 设置是否显示鼠标追踪器
/// \param show:是否显示
///
void TracerManager::showTracer(bool show)
{
    m_isShowTracer = show;
    // 设置x轴追踪器的可见性
    if(m_xTracer)
        m_xTracer->setVisible(m_isShowTracer);
    // 设置y轴追踪器的可见性
    if(m_yTracer)
        m_yTracer->setVisible(m_isShowTracer);


    // 设置所有数据追踪器的可见性
    for(MyTracer *tracer : m_dataTracers)
    {
        // 检查对象是否有效
        if(tracer)
            tracer->setVisible(m_isShowTracer);
    }
    // 设置直线追踪器的可见性
    if(m_lineTracer)
        m_lineTracer->setVisible(m_isShowTracer);
}
///
/// \brief 是否显示鼠标追踪器
/// \return
///
bool TracerManager::isShowTracer()
{
    return m_isShowTracer;
}

void TracerManager::updateMouseLabelPosition(QCPItemText *label, const double &x, const double &y)
{
    label->setPositionAlignment(Qt::AlignRight | Qt::AlignTop);

    // 计算标签位置（鼠标位置 + 偏移量）
    double xVal = x + m_offsetX;
    double yVal = y + m_offsetY;

    QCustomPlot *customplot = m_customPlot;
    //    {
    //        QCPRange xRange = customplot->xAxis->range();
    //        QCPRange yRange = customplot->yAxis->range();

    //        // 判断是否在坐标轴范围内
    //        bool isVisible = (x >= xRange.lower && x <= xRange.upper) &&
    //                        (y >= yRange.lower && y <= yRange.upper);
    //        label->setVisible(isVisible);
    //        return;
    //    }

    if (xVal > customplot->width()) xVal = customplot->width();
    if (yVal > customplot->height()) yVal = customplot->height();

    // 更新标签位置
    label->position->setCoords(xVal, yVal);

    // 设置标签文本
    label->setText(QString("X: %1 \n Y: %2").arg(x).arg(y));
}
